// Copyright (c) 2022 CHANGLEI. All rights reserved.

import 'package:aircraft_war/bloc/game_state_cubit.dart';
import 'package:aircraft_war/components/bullet.dart';
import 'package:aircraft_war/enums/aircraft_state.dart';
import 'package:aircraft_war/generated/assets.dart';
import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
import 'package:flame/flame.dart';

/// Created by changlei on 2022/5/19.
///
/// 敌机
class EnemyAircraft extends GameStatePositionComponent with CollisionCallbacks {
  /// 敌机
  EnemyAircraft({
    required this.type,
    super.anchor,
    super.position,
    super.angle,
  }) : super(size: type.size);

  /// 敌机类型
  final EnemyType type;

  late final _aircraft = SpriteAnimationGroupComponent<AircraftState>(
    animations: {
      AircraftState.alive: SpriteAnimation.spriteList(
        type.alivePaths.map((e) => Sprite(Flame.images.fromCache(e))).toList(),
        stepTime: 0.1,
      ),
      AircraftState.hit: SpriteAnimation.spriteList(
        type.hitPaths.map((e) => Sprite(Flame.images.fromCache(e))).toList(),
        stepTime: 0.1,
        loop: false,
      )..onComplete = _onHitComplete,
      AircraftState.destroy: SpriteAnimation.spriteList(
        type.destroyPaths.map((e) => Sprite(Flame.images.fromCache(e))).toList(),
        stepTime: 0.1,
        loop: false,
      )..onComplete = _onDestroy,
    },
    size: size,
    current: AircraftState.alive,
  );

  late int _aliveValue = type.aliveValue;

  late double _speed = type.speed;

  /// 增加速度
  void growth(double offset) {
    _speed += offset;
  }

  /// 是否存活
  bool get isActive => _aircraft.current != AircraftState.destroy;

  @override
  Future<void> onLoad() async {
    await add(_aircraft);
    await add(PolygonHitbox.relative(
      type.vertices,
      parentSize: size,
    ));
  }

  @override
  void update(double dt) {
    if (gameRef.stateCubit.state != GameState.running) {
      return;
    }
    if (!containsOfParent(position) && !containsOfParent(position + size)) {
      removeFromParent();
      return;
    }
    position.y += _speed * dt;
  }

  @override
  void onNewState(GameState state) {
    switch (state) {
      case GameState.idle:
      case GameState.pending:
      case GameState.stopped:
        removeFromParent();
        break;
      case GameState.pausing:
        break;
      case GameState.running:
        break;
    }
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    super.onCollision(intersectionPoints, other);
    if (!isActive || !gameRef.isRunning || other is! Bullet) {
      return;
    }
    _aliveValue--;
    if (_aliveValue <= 0) {
      destroy();
    } else if (_aircraft.current == AircraftState.alive) {
      _aircraft.current = AircraftState.hit;
    }
  }

  /// 消灭并记分
  void destroy() {
    if (!isActive) {
      return;
    }
    _aircraft.current = AircraftState.destroy;
    gameRef.scoreCubit.hit(type);
  }

  void _onHitComplete() {
    if (isActive) {
      _aircraft.animation?.reset();
      _aircraft.current = AircraftState.alive;
    }
  }

  void _onDestroy() {
    _aliveValue = 0;
    removeFromParent();
  }
}

/// 敌机类型
enum EnemyType {
  /// 小飞机
  small(
    size: Size(57, 43),
    speed: 200,
    aliveValue: 1,
    alivePaths: [
      Images.enemy1,
    ],
    hitPaths: [
      Images.enemy1,
    ],
    destroyPaths: [
      Images.enemy1,
      Images.enemy1_down1,
      Images.enemy1_down2,
      Images.enemy1_down3,
      Images.enemy1_down4,
    ],
    vertices: [
      Offset(-0.5, -1.0),
      Offset(-0.5, -0.4),
      Offset(-1.0, -0.4),
      Offset(0.0, 1.0),
      Offset(1.0, -0.4),
      Offset(0.5, -0.4),
      Offset(0.5, -1.0),
    ],
  ),

  /// 中飞机
  middle(
    size: Size(69, 99),
    speed: 100,
    aliveValue: 6,
    alivePaths: [
      Images.enemy2,
    ],
    hitPaths: [
      Images.enemy2,
      Images.enemy2_hit,
    ],
    destroyPaths: [
      Images.enemy2,
      Images.enemy2_hit,
      Images.enemy2_down1,
      Images.enemy2_down2,
      Images.enemy2_down3,
      Images.enemy2_down4,
    ],
    vertices: [
      Offset(-0.3, -1.0),
      Offset(-0.3, -0.4),
      Offset(-1.0, -0.4),
      Offset(-1.0, 0.3),
      Offset(0.0, 1.0),
      Offset(1.0, 0.3),
      Offset(1.0, -0.4),
      Offset(0.3, -0.4),
      Offset(0.3, -1.0),
    ],
  ),

  /// 大boss
  large(
    size: Size(169, 258),
    speed: 40,
    aliveValue: 30,
    alivePaths: [
      Images.enemy3_n1,
      Images.enemy3_n2,
    ],
    hitPaths: [
      Images.enemy3_n1,
      Images.enemy3_n2,
      Images.enemy3_hit,
    ],
    destroyPaths: [
      Images.enemy3_n1,
      Images.enemy3_n2,
      Images.enemy3_hit,
      Images.enemy3_down1,
      Images.enemy3_down2,
      Images.enemy3_down3,
      Images.enemy3_down4,
      Images.enemy3_down5,
      Images.enemy3_down6,
    ],
    vertices: [
      Offset(-0.2, -0.4),
      Offset(-0.65, -0.6),
      Offset(-0.65, -1.0),
      Offset(-0.8, -1.0),
      Offset(-0.8, 0.33),
      Offset(-1.0, 0.5),
      Offset(-0.2, 1.0),
      Offset(0.2, 1.0),
      Offset(1.0, 0.5),
      Offset(0.8, 0.33),
      Offset(0.8, -1.0),
      Offset(0.65, -1.0),
      Offset(0.65, -0.6),
      Offset(0.2, -0.4),
    ],
  );

  /// 敌机类型
  const EnemyType({
    required Size size,
    required this.speed,
    required this.aliveValue,
    required this.alivePaths,
    required this.hitPaths,
    required this.destroyPaths,
    required List<Offset> vertices,
  })  : _size = size,
        _vertices = vertices;

  final Size _size;

  /// 速度
  final double speed;

  /// 生命值
  final int aliveValue;

  /// 存活的图片
  final List<String> alivePaths;

  /// 命中的图片
  final List<String> hitPaths;

  /// 消亡的图片
  final List<String> destroyPaths;

  final List<Offset> _vertices;

  /// 多边形检查
  List<Vector2> get vertices => _vertices.map((e) => e.toVector2()).toList();

  /// 大小
  Vector2 get size => _size.toVector2().scaled(0.6);
}
